﻿using System; 
using System.Collections.Generic;
using System.Text;

namespace AJAXChatClient.Flash.Net
{
    /// <summary><para>
    /// The XMLSocket class implements client sockets that let the Flash Player or AIR application 
    /// communicate with a server computer identified by an IP address or domain name. 
    /// The XMLSocket class is useful for client-server applications that require low latency, 
    /// such as real-time chat systems. A traditional HTTP-based chat solution frequently polls the server 
    /// and downloads new messages using an HTTP request. In contrast, an XMLSocket chat solution maintains 
    /// an open connection to the server, which lets the server immediately send incoming messages without 
    /// a request from the client. To use the XMLSocket class, the server computer must run a daemon that 
    /// understands the protocol used by the XMLSocket class. The protocol is described in the following list:
    /// </para><list type="bullet">
    /// <item><description>
    /// XML messages are sent over a full-duplex TCP/IP stream socket connection.
    /// </description></item>
    /// <item><description>
    /// Each XML message is a complete XML document, terminated by a zero (0) byte.
    /// </description></item>
    /// <item><description>
    /// An unlimited number of XML messages can be sent and received over a single XMLSocket connection.
    /// </description></item>
    /// </list><para>
    /// The <see cref="XMLSocket.Connect(string,int)"/> method can connect only to TCP port numbers greater than or equal to 1024. 
    /// One consequence of this restriction is that the server daemons that communicate with the XMLSocket object must also 
    /// be assigned to port numbers greater than or equal to 1024. Port numbers below 1024 are often used by system services 
    /// such as FTP, Telnet, and HTTP, so XMLSocket objects are barred from these ports for security reasons. 
    /// The port number restriction limits the possibility that these resources will be inappropriately accessed and abused.
    /// </para><para>
    /// Setting up a server to communicate with the XMLSocket object can be challenging. If your application does not require 
    /// real-time interactivity, use the URLLoader class instead of the XMLSocket class. To use the methods of the XMLSocket class, 
    /// you must first use the constructor, new <c>XMLSocket</c>, to create an XMLSocket object.
    /// </para><para>
    /// When you use this class, consider the following security model:
    /// </para><list type="bullet">
    /// <item><description>
    /// Sending or receiving data is not allowed if the calling file is in the local-with-file-system sandbox 
    /// and the target resource is from a network sandbox.
    /// </description></item>
    /// <item><description>
    /// Sending or receiving data is also not allowed if the calling file is from a network sandbox 
    /// and the target resource is local.
    /// </description></item>
    /// <item><description>
    /// The calling file and the network resource being accessed must be in exactly the same domain. 
    /// For example, a file at www.adobe.com can send or receive data only from sources that are also at www.adobe.com.
    /// </description></item>
    /// <item><description>
    /// Websites can permit cross-domain access to a resource through a cross-domain policy file.
    /// </description></item>
    /// </list><para>
    /// However, in Adobe AIR, content in the <c>application</c> security sandbox 
    /// (content installed with the AIR application) are not restricted by these security limitations.
    /// </para></summary>
    public class XMLSocket
    {
        public XMLSocket() : this(null, 0) { }

        public XMLSocket(string host) : this(host, 0) { }

        /// <summary>
        /// Creates a new XMLSocket object. 
        /// The XMLSocket object is not initially connected to any server. 
        /// You must call the <see cref="Connect()"/> method to connect the object to a server.
        /// </summary>
        /// <param name="host">
        /// A fully qualified DNS domain name or an IP address in the form aaa.bbb.ccc.ddd. 
        /// You can also specify <c>null</c> to connect to the host server on which the SWF file resides. 
        /// If the calling file is a SWF file running in a web browser, 
        /// <paramref name="host"/> must be in the same domain as the calling file.
        /// </param>
        /// <param name="port">
        /// The TCP port number on the host used to establish a connection. 
        /// The port number must be 1024 or greater, unless a policy file is being used.
        /// </param>
        /// <seealso cref="Connect(string,int)"/>
        public XMLSocket(string host, int port)
        {
        }

        /// <summary>
        /// Indicates whether this XMLSocket object is currently connected. 
        /// You can also check whether the connection succeeded by registering for the 
        /// <see cref="Connect"/> event and <see cref="IOError"/> event.
        /// </summary>
        /// <seealso cref="Connect"/>
        /// <seealso cref="IOError"/>
        public bool Connected
        {
            get;
        }

        /// <summary>
        /// Closes the connection specified by the XMLSocket object. 
        /// The <see cref="Close"/> event is dispatched only when the server closes the connection; 
        /// it is not dispatched when you call the close() method.
        /// </summary>
        /// <seealso cref="Connect(string,int)"/>
        public void Close()
        {
        }

        /// <summary><para>
        /// Establishes a connection to the specified Internet host using the specified TCP port. 
        /// By default you can only connect to port 1024 or higher, unless you are using a policy file.
        /// </para><para>
        /// If you specify <c>null</c> for the host parameter, 
        /// the host contacted is the one where the file calling <see cref="Connect(string,int)"/> resides. 
        /// For example, if the calling file was downloaded from www.adobe.com, 
        /// specifying <c>null</c> for the host parameter is the same as entering the IP address for www.adobe.com.
        /// </para><para>
        /// By default, the value you pass for <paramref name="host"/> must be in exactly the same domain and 
        /// the value you pass for <paramref name="port"/> must be 1024 or above. 
        /// For example, a SWF file at www.adobe.com can send or receive variables only from SWF files that are also at www.adobe.com. 
        /// If you want to connect to a socket on a different host than the one from which the connecting SWF file was served, 
        /// or if you want to connect to a port lower than 1024 on any host, 
        /// you must obtain an <c>xmlsocket:</c> policy file from the host to which you are connecting.
        /// </para><para>
        /// You can prevent a file from using this method by setting the <c>allowNetworking</c> parameter 
        /// of the <c>object</c> and <c>embed</c> tags in the HTML page that contains the SWF content.
        /// </para></summary>
        /// <param name="host">
        /// A fully qualified DNS domain name or an IP address in the form aaa.bbb.ccc.ddd. 
        /// You can also specify <c>null</c> to connect to the host server on which the SWF file resides. 
        /// If the calling file is a SWF file running in a web browser, 
        /// <paramref name="host"/> must be in the same domain as the calling file.
        /// </param>
        /// <param name="port">
        /// The TCP port number on the host used to establish a connection. 
        /// The port number must be 1024 or greater, unless a policy file is being used.
        /// </param>
        public void Connect(string host, int port)
        {
        }

        /// <summary><para>
        /// Converts the XML object or data specified in the <paramref name="data"/> parameter to a string and transmits it to the server, 
        /// followed by a zero (0) byte. If <paramref name="data"/> is an XML object, the string is the XML textual representation of the XML object. 
        /// The send operation is asynchronous; it returns immediately, but the data may be transmitted at a later time. 
        /// The <see cref="Send(object)"/> method does not return a value indicating whether the data was successfully transmitted.
        /// </para><para>
        /// If you do not connect the XMLSocket object to the server using <see cref="Connect(string,int)"/>, 
        /// the <see cref="Send(object)"/> operation fails.
        /// </para></summary>
        /// <param name="data"> An XML object or other data to transmit to the server.</param>
        /// <seealso cref="Connect(string,int)"/>
        public void Send(object data)
        {
        }

        public class CloseEventArgs
        {
            public readonly bool Bubbles = false;
            /// <summary>
            /// false; there is no default behavior to cancel.
            /// </summary>
            public readonly bool Cancelable = false;
            /// <summary>
            /// The object that is actively processing the Event object with an event listener.
            /// </summary>
            public readonly object CurrentTarget;
            /// <summary>
            /// The object whose connection has been closed.
            /// </summary>
            public readonly object Target;
        }

        public delegate void CloseEventHandler(CloseEventArgs eventArgs);

        /// <summary>
        /// Dispatched when the server closes the socket connection. 
        /// The <c>Close</c> event is dispatched only when the server closes the connection; 
        /// it is not dispatched when you call the <see cref="Close()"/> method.
        /// </summary>
        public event CloseEventHandler CloseEvent;

        public class ConnectEventArgs
        {
            public readonly bool Bubbles = false;
            /// <summary>
            /// false; there is no default behavior to cancel.
            /// </summary>
            public readonly bool Cancelable = false;
            /// <summary>
            /// The object that is actively processing the Event object with an event listener.
            /// </summary>
            public readonly object CurrentTarget;
            /// <summary>
            /// The Socket or XMLSocket object that has established a network connection.
            /// </summary>
            public readonly object Target;
        }

        public delegate void ConnectEventHandler(ConnectEventArgs eventArgs);

        /// <summary>
        /// Dispatched after a successful call to the <see cref="Connect(string,int)"/> method.
        /// </summary>
        public event ConnectEventHandler ConnectEvent;

        public class DataEventArgs
        {
            public readonly bool Bubbles = false;
            /// <summary>
            /// false; there is no default behavior to cancel.
            /// </summary>
            public readonly bool Cancelable = false;
            /// <summary>
            /// The object that is actively processing the Event object with an event listener.
            /// </summary>
            public readonly object CurrentTarget;
            /// <summary>
            /// The raw data loaded into Flash Player or Adobe AIR.
            /// </summary>
            public readonly object Data;
            /// <summary>
            /// The XMLSocket object receiving data.
            /// </summary>
            public readonly object Target;
        }

        public delegate void DataEventHandler(DataEventArgs eventArgs);

        /// <summary>
        /// Dispatched after raw data is sent or received.
        /// </summary>
        public event DataEventHandler DataEvent;

        public class IOErrorEventArgs
        {
            public readonly bool Bubbles = false;
            /// <summary>
            /// false; there is no default behavior to cancel.
            /// </summary>
            public readonly bool Cancelable = false;
            /// <summary>
            /// The object that is actively processing the Event object with an event listener.
            /// </summary>
            public readonly object CurrentTarget;
            /// <summary>
            /// A reference number associated with the specific error.
            /// </summary>
            public readonly int ErrorID;
            /// <summary>
            /// The network object experiencing the input/output error.
            /// </summary>
            public readonly object Target;
            /// <summary>
            /// Text to be displayed as an error message.
            /// </summary>
            public readonly string Text;
        }

        public delegate void IOErrorEventHandler(IOErrorEventArgs eventArgs);

        /// <summary>
        /// Dispatched when an input/output error occurs that causes a send or receive operation to fail.
        /// </summary>
        public event IOErrorEventHandler IOErrorEvent;

        public class SecurityErrorEventArgs
        {
            public readonly bool Bubbles = false;
            /// <summary>
            /// false; there is no default behavior to cancel.
            /// </summary>
            public readonly bool Cancelable = false;
            /// <summary>
            /// The object that is actively processing the Event object with an event listener.
            /// </summary>
            public readonly object CurrentTarget;
            /// <summary>
            /// The network object reporting the security error.
            /// </summary>
            public readonly object Target;
            /// <summary>
            /// Text to be displayed as an error message.
            /// </summary>
            public readonly string Text;
        }

        public delegate void SecurityErrorEventHandler(SecurityErrorEventArgs eventArgs);

        /// <summary>
        /// Dispatched if a call to the <see cref="Connect(string,int)"/> method attempts to connect 
        /// either to a server outside the caller's security sandbox or to a port lower than 1024.
        /// </summary>
        /// <seealso cref="Connect(string,int)"/>
        public event SecurityErrorEventHandler SecurityErrorEvent;
    }
}
